#ifndef NCSPROPMGR_P_H
#define NCSPROPMGR_P_H

#include "ncspropmgr.h"
#include <memory>
#include <set>
#include <QTimer>

class NcsPropPrivate
{
public:
    NcsPropPrivate(NcsProp* _q_not_null) : 
        q(_q_not_null)
    { }

    NcsProp* parent() const { return m_parent; }

    //! modify property type. one can put some notification code here if required. 
    void setPropType(int prop_type) { m_proptype = prop_type; }
  
    bool status(int status_code) const { return m_flags & (1<<status_code); }

    void setStatus(int status_code, bool f_set) 
    {
        if (f_set)
            m_flags |= (1<<status_code); 
        else
            m_flags &= ~(1<<status_code); 
    }

    void clearStatus() { m_flags = 0; }

public:
    NcsProp* q = nullptr;
    NcsPropMgr* mgr = nullptr; 
    QVariant val; 
    QString label; // label is displayed ahead of property editor. 
    int m_proptype = 0;
    uint32_t m_flags = 0; 
    NcsProp*         m_parent = nullptr; 
    QList<NcsProp*>  m_subprops; 
    QVariantMap      m_attrib; 
};

class NcsPropMgrPrivate
{
    typedef NcsPropMgr This; 
public:
    NcsPropMgrPrivate(NcsPropMgr* _q_not_null) 
        : q(_q_not_null)
        , m_root(_q_not_null)
    { }

    ~NcsPropMgrPrivate()
    {
        if (m_root.subProperties().size() > 0)
        {
            auto subprops = m_root.subProperties(); // copy sub properties. 
            for (auto subp : subprops)
                q->removeProperty(subp); 
        }
    }

    void startFontChangeWatcher(); 
    void slotFontDBDelayedChange();

    void cacheAdd(NcsProp* p) { m_propcache.insert(PNcsPropItem(p)); } 

    void cacheClear()
    {
        for (auto p : m_propcache)
            delete p.ptr;
        m_propcache.clear();
    }

    // get one NcsProp corpse from cache and return.  the pointer is remove it from cache. 
    PNcsProp cacheTake(int prop_typeid)
    {
        PNcsProp p = nullptr;
        auto it = m_propcache.find(prop_typeid);
        if (it != m_propcache.end())
        {
            p = it->ptr;
            m_propcache.erase(it);
        }
        return p;
    }

public:
    NcsPropMgr* q = nullptr;
    NcsProp     m_root;     //!  invisible root

    QMap<NcsProp*, This::EditorFn>    prop_factory; //某个属性独有的编辑器工厂函数.  次高优先级
    QMap<int, This::EditorFn>         type_factory;  // 每个类型的编辑器工厂函数.  普通优先级.

    QMap<NcsProp*, This::DecoratorFn> prop_decrator; //某个属性独有的编辑器工厂函数.  次高优先级
    QMap<int, This::DecoratorFn>      type_decrator;  // 每个类型的编辑器工厂函数.  普通优先级. 

    QStringList m_fontfamilies; 
    QTimer*     m_fontDBChangeTimer  = nullptr; 

    NcsPropMgr::DeleteBehavior m_deletebehavior = NcsPropMgr::DELETE_DIRECTLY;

    
    struct PNcsPropItem
    { 
        PNcsProp ptr;
        int proptypeid; 

        explicit PNcsPropItem(PNcsProp _ptr)
        {
            ptr = _ptr;
            proptypeid = _ptr->propType();
        }

        PNcsPropItem(int pptypeid)
        {
            ptr = nullptr;
            proptypeid = pptypeid;
        }

        bool operator< (const PNcsPropItem& rhs) const 
        {
            return proptypeid < rhs.proptypeid; 
        }

    };

    std::multiset<PNcsPropItem> m_propcache; // cache for property. 
}; 

#endif //NCSPROPMGR_P_H
